﻿using System;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;

namespace ZFCNew.Code
{
    /// <summary>
    /// Currently this class only supports Json search result formats.
    /// This works for both twitter and facebook.
    /// </summary>
    /// <typeparam name="TRes"></typeparam>
    public class GenericSearch<TRes> where TRes: new()
    {
        public event EventHandler<SearchBaseEventArgs<TRes>> SearchCompleted;
        public event EventHandler OnError;
        public event EventHandler OnCancel;
        private string SearchApiFormat { get; set; }

        private readonly WebClient _wc;

        public GenericSearch(string apiFormat)
        {
            SearchApiFormat = apiFormat;
            _wc = new WebClient();
            _wc.DownloadStringCompleted += ApiSearchCompleted;
        }

        void ApiSearchCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                if (OnCancel != null)
                {
                    OnCancel(this, EventArgs.Empty);
                }
                return;
            } 

            if (e.Error == null && e.Result != null)
            {
                var ms = new MemoryStream(Encoding.UTF8.GetBytes(e.Result));
                var res = (TRes)new DataContractJsonSerializer(typeof(TRes)).ReadObject(ms);
                if (SearchCompleted != null)
                {
                    SearchCompleted(this, new SearchBaseEventArgs<TRes> { Results = res });
                }
            }
            else
            {
                if (OnError != null)
                {
                    OnError(this, EventArgs.Empty);
                }
            }
        }

        public void Search(params object[] args)
        {
            string url = string.Format(SearchApiFormat, args);
            SearchDirect(url);
        }

        /// <summary>
        /// Use this when we already know the complete search URL 
        /// and don't have to construct it with SearchApiFormat
        /// </summary>
        /// <param name="url"></param>
        public void SearchDirect(string url)
        {
            if (_wc.IsBusy) _wc.CancelAsync();
            try
            {
                _wc.DownloadStringAsync(new Uri(url));
            }
            catch
            {
                _wc.CancelAsync();
            }
        }
    }

    public class SearchBaseEventArgs<TRes> : EventArgs
    {
        public TRes Results { get; set; }
    }
}
